package com.hy.admin.service.impl;

import com.github.pagehelper.PageHelper;
import com.hy.admin.dao.*;
import com.hy.admin.entity.*;
import com.hy.admin.enums.EnumOperationType;
import com.hy.admin.enums.EnumPayState;
import com.hy.admin.enums.EnumStatus;
import com.hy.admin.helper.response.MemberYangCoinDetailResponse;
import com.hy.admin.helper.response.OrderResponse;
import com.hy.admin.service.CourseService;
import com.hy.admin.service.YangCoinService;
import com.hy.core.response.ServicesResult;
import com.hy.utils.CommonUtility;
import org.apache.commons.httpclient.HttpStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.UUID;

@Service
public class YangCoinServiceImpl implements YangCoinService {

    @Autowired
    private MemberYangCoinDao memberYangCoinDao;
    @Autowired
    private MemberYangCoinDetailDao memberYangCoinDetailDao;
    @Autowired
    private CourseOrderDao courseOrderDao;
    @Autowired
    private CourseDao courseDao;
    @Autowired
    private YangCoinDao yangCoinDao;
    @Autowired
    private YangCoinOrderDao yangCoinOrderDao;
    @Autowired
    private QuestionDao questionDao;
    @Autowired
    private MemberPayQuestionDao memberPayQuestionDao;
    @Autowired
    private QuestionClickDao questionClickDao;
    @Autowired
    private CourseService courseService;

    /***
     * 氧币充值
     * @param memberId
     * @param coinId
     * @return
     * @throws Exception
     */
    @Override
    public ServicesResult<OrderResponse> recharge(Long memberId, Long coinId){
        ServicesResult<OrderResponse> servicesResult = new ServicesResult<>();
        //校验请求参数
        if (memberId == null || memberId < 0){
            servicesResult.setStatusCode(HttpStatus.SC_INTERNAL_SERVER_ERROR);
            servicesResult.setStatusMsg("请求报文有误");
            return servicesResult;
        }
        if (coinId == null || coinId < 0){
            servicesResult.setStatusCode(HttpStatus.SC_INTERNAL_SERVER_ERROR);
            servicesResult.setStatusMsg("请求报文有误");
            return servicesResult;
        }
        YangCoinEntity yangCoin = yangCoinDao.selectByPrimaryKey(coinId);
        if(yangCoin == null){
            servicesResult.setStatusCode(HttpStatus.SC_INTERNAL_SERVER_ERROR);
            servicesResult.setStatusMsg("请求参数有误");
            return servicesResult;
        }
        String uuid = UUID.randomUUID().toString().replace("-", "").toLowerCase();
        YangCoinOrderEntity order = new YangCoinOrderEntity();
        order.setMemberId(memberId);
        order.setCoinId(coinId);
        order.setCoinCount(yangCoin.getCoinCount());
        order.setPrice(yangCoin.getPrice());
        order.setPayState(EnumPayState.UNPAID.getId());
        order.setStatus(EnumStatus.VALID.getId());
        order.setUuid(uuid);
        int result = yangCoinOrderDao.insertSelective(order);
        if(result <= 0){
            servicesResult.setStatusCode(HttpStatus.SC_INTERNAL_SERVER_ERROR);
            servicesResult.setStatusMsg("数据插入失败");
            return servicesResult;
        }
        Long orderId = yangCoinOrderDao.selectByUuid(uuid);
        OrderResponse orderResponse = new OrderResponse();
        orderResponse.setId(orderId);
        orderResponse.setResult(true);
        servicesResult.setResult(orderResponse);
        return servicesResult;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ServicesResult<Boolean> paySuccess(Long yangCoinOrderId) throws Exception {
        ServicesResult<Boolean> servicesResult = new ServicesResult<>();
        //校验请求参数
        if (yangCoinOrderId == null || yangCoinOrderId < 0){
            servicesResult.setStatusCode(HttpStatus.SC_INTERNAL_SERVER_ERROR);
            servicesResult.setStatusMsg("请求报文有误");
            return servicesResult;
        }
        //查询订单状态
        YangCoinOrderEntity order = yangCoinOrderDao.selectByPrimaryKey(yangCoinOrderId);
        if (order == null){
            servicesResult.setStatusCode(HttpStatus.SC_INTERNAL_SERVER_ERROR);
            servicesResult.setStatusMsg("订单不存在");
            return servicesResult;
        }
        //修改订单状态
        int result = yangCoinOrderDao.changePayState(yangCoinOrderId, EnumPayState.PAID.getId());
        if(result <= 0){
            servicesResult.setStatusCode(HttpStatus.SC_INTERNAL_SERVER_ERROR);
            servicesResult.setStatusMsg("订单状态修改失败");
            return servicesResult;
        }
        //增加用户氧币
        servicesResult = changeYangCoin(order.getMemberId(), order.getCoinCount(), EnumOperationType.RECHARGE.getId());
        if(!servicesResult.getResult()){
            throw new Exception("增加氧币失败");
        }
        return servicesResult;
    }

    /**
     * 氧币支付
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ServicesResult<Boolean> pay(Long courseOrderId, Long coinCount) throws Exception {
        ServicesResult<Boolean> servicesResult = new ServicesResult<>();
        //校验请求参数
        if (courseOrderId == null || courseOrderId < 0){
            servicesResult.setStatusCode(HttpStatus.SC_INTERNAL_SERVER_ERROR);
            servicesResult.setStatusMsg("请求报文有误");
            return servicesResult;
        }
        if (coinCount == null || coinCount < 0){
            servicesResult.setStatusCode(HttpStatus.SC_INTERNAL_SERVER_ERROR);
            servicesResult.setStatusMsg("请求报文有误");
            return servicesResult;
        }
        //根据查询课程订单数据
        CourseOrderEntity order = courseOrderDao.selectByPrimaryKey(courseOrderId);
        if(order == null){
            servicesResult.setStatusCode(HttpStatus.SC_INTERNAL_SERVER_ERROR);
            servicesResult.setStatusMsg("支付订单不存在");
            return servicesResult;
        }
        CourseEntity course = courseDao.selectByPrimaryKey(order.getCourseId());
        if(course == null){
            servicesResult.setStatusCode(HttpStatus.SC_INTERNAL_SERVER_ERROR);
            servicesResult.setStatusMsg("购买课程不存在");
            return servicesResult;
        }
        //修改家长氧币数量
        servicesResult = changeYangCoin(order.getMemberId(), coinCount, EnumOperationType.CONSUME.getId());
        if(servicesResult.getResult()) {
            //修改教师氧币数量
            servicesResult = changeYangCoin(course.getMemberId(), coinCount, EnumOperationType.INCOME_COURSE.getId());
            if(!servicesResult.getResult()){
                throw new Exception("教师氧币增加失败");
            }
            //修改订单支付状态
            servicesResult = courseService.paySuccess(courseOrderId);
            if(!servicesResult.getResult()){
                throw new Exception("订单状态修改失败");
            }
        }
        return servicesResult;
    }

    @Override
    public ServicesResult<Boolean> payAnswer(Long memberId, Long questionId, Long coinCount) throws Exception {
        ServicesResult<Boolean> servicesResult = new ServicesResult<>();
        //校验请求参数
        if (memberId == null || memberId <= 0){
            servicesResult.setStatusCode(HttpStatus.SC_INTERNAL_SERVER_ERROR);
            servicesResult.setStatusMsg("请求报文有误");
            return servicesResult;
        }
        if (coinCount == null || coinCount <= 0){
            servicesResult.setStatusCode(HttpStatus.SC_INTERNAL_SERVER_ERROR);
            servicesResult.setStatusMsg("请求报文有误");
            return servicesResult;
        }
        int isPay = memberPayQuestionDao.selectByMIdAndQId(memberId,questionId);
        if(isPay > 0){
            servicesResult.setStatusCode(HttpStatus.SC_INTERNAL_SERVER_ERROR);
            servicesResult.setStatusMsg("请勿重复购买");
            return servicesResult;
        }
        //修改家长氧币数量
        servicesResult = changeYangCoin(memberId, coinCount, EnumOperationType.CONSUME.getId());
        if(servicesResult.getResult()) {
            QuestionEntity question = questionDao.selectByPrimaryKey(questionId);
            //修改教师氧币数量
            servicesResult = changeYangCoin(question.getTeacherId(), coinCount, EnumOperationType.INCOME_ANSWER.getId());
            if(!servicesResult.getResult()){
                throw new Exception("教师氧币增加失败");
            }
            //记录用户购买的问题答案
            MemberPayQuestionEntity mpqEntity = new MemberPayQuestionEntity();
            mpqEntity.setMemberId(memberId);
            mpqEntity.setQuestionId(questionId);
            mpqEntity.setStatus(EnumStatus.VALID.getId());
            mpqEntity.setCreateTime(new Date());
            int result = memberPayQuestionDao.insertSelective(mpqEntity);
            if(result <= 0){
                throw new Exception("购买记录添加失败");
            }
            //增加问答点击量
            int count = questionClickDao.selectCountByQIdAndMId(questionId, memberId);
            if(count == 0){
                //新增用户点击数据
                QuestionClickEntity queClick = new QuestionClickEntity();
                queClick.setCreateTime(new Date());
                queClick.setMemberId(memberId);
                queClick.setQuestionId(questionId);
                queClick.setStatus(EnumStatus.VALID.getId());
                count = questionClickDao.insertSelective(queClick);
                if(count > 0){
                    //增加点击量
                    questionDao.updateClickNum(questionId);
                }
            }
            servicesResult.setResult(true);
        }
        return servicesResult;
    }

    @Override
    public ServicesResult<List<MemberYangCoinDetailResponse>> detail(Long memberId, Integer pageNum, Integer pageSize) {
        ServicesResult<List<MemberYangCoinDetailResponse>> servicesResult = new ServicesResult<>();

        //校验请求参数
        if (memberId == null || memberId < 0){
            servicesResult.setStatusCode(HttpStatus.SC_INTERNAL_SERVER_ERROR);
            servicesResult.setStatusMsg("请求报文有误");
            return servicesResult;
        }

        //设置分页条件，Parameters:pageNum 页码pageSize 每页显示数量count 是否进行count查询
        if(pageNum == null || pageNum <= 0){
            //初始页码为1
            pageNum = 1;
        }
        if(pageSize == null || pageSize <= 0){
            //初始数量为20
            pageSize = 20;
        }
        PageHelper.startPage(pageNum, pageSize);

        List<MemberYangCoinDetailResponse> dList = memberYangCoinDetailDao.selectByMemberId(memberId);
        servicesResult.setResult(dList);
        return servicesResult;
    }

    @Override
    public ServicesResult<List<YangCoinEntity>> list() {
        ServicesResult<List<YangCoinEntity>> servicesResult = new ServicesResult<>();
        List<YangCoinEntity> coinList = yangCoinDao.selectAll();
        servicesResult.setResult(coinList);
        return servicesResult;
    }

    @Transactional(rollbackFor = Exception.class)
    public ServicesResult<Boolean> changeYangCoin(Long memberId, Long coinCount, Integer operationType) throws Exception {
        ServicesResult<Boolean> servicesResult = new ServicesResult<>();
        servicesResult.setResult(false);
        MemberYangCoinEntity memberYangCoin = memberYangCoinDao.selectByMemberId(memberId);
        if(memberYangCoin == null && operationType == EnumOperationType.CONSUME.getId()){
            servicesResult.setStatusCode(HttpStatus.SC_INTERNAL_SERVER_ERROR);
            servicesResult.setStatusMsg("氧币数量为零，无法支付");
            return servicesResult;
        }
        if(memberYangCoin != null && operationType == EnumOperationType.CONSUME.getId()
                && memberYangCoin.getAmount() < coinCount){
            servicesResult.setStatusCode(HttpStatus.SC_INTERNAL_SERVER_ERROR);
            servicesResult.setStatusMsg("氧币数量不足，无法支付");
            return servicesResult;
        }
        Long beforeAmount = memberYangCoin == null ? 0 : memberYangCoin.getAmount();
        Integer result;
        Calendar cal = Calendar.getInstance();
        Date time = cal.getTime();
        if (memberYangCoin == null) {
            //用户的第一次充值或收入
            memberYangCoin = new MemberYangCoinEntity();
            memberYangCoin.setMemberId(memberId);
            memberYangCoin.setAmount(coinCount);
            memberYangCoin.setStatus(EnumStatus.VALID.getId());
            memberYangCoin.setCreateTime(time);
            memberYangCoin.setUpdateTime(time);
            result = memberYangCoinDao.insertSelective(memberYangCoin);
        } else {
            if(operationType == EnumOperationType.CONSUME.getId()){
                memberYangCoin.setAmount(memberYangCoin.getAmount() - coinCount);
            }else {
                memberYangCoin.setAmount(memberYangCoin.getAmount() + coinCount);
            }
            memberYangCoin.setUpdateTime(time);
            result = memberYangCoinDao.updateByPrimaryKeySelective(memberYangCoin);

        }
        if (result <= 0) {
            servicesResult.setStatusCode(HttpStatus.SC_INTERNAL_SERVER_ERROR);
            servicesResult.setStatusMsg("氧币数量修改失败");
        }
        //插入氧币明细表
        MemberYangCoinDetailEntity memberYangCoinDetail = new MemberYangCoinDetailEntity();
        memberYangCoinDetail.setBeforeAmount(beforeAmount);
        memberYangCoinDetail.setCoinCount(coinCount);
        memberYangCoinDetail.setOperationType(operationType);
        memberYangCoinDetail.setMemberId(memberId);
        memberYangCoinDetail.setStatus(EnumStatus.VALID.getId());

        result = memberYangCoinDetailDao.insertSelective(memberYangCoinDetail);

        if (result <= 0) {
            //如插入氧币明细表失败则事务回滚
            servicesResult.setStatusCode(HttpStatus.SC_INTERNAL_SERVER_ERROR);
            servicesResult.setStatusMsg("氧币明细插入失败");
            throw new Exception("氧币明细插入失败");
        }

        servicesResult.setResult(true);
        return  servicesResult;
    }
}
